package cn.itsource.recursion.file;

import java.io.File;

/**
 *	递归：
 *		1. 概念：是一种思想。在方法内部调用自己的方法。（自己干自己）
 *		2. 作用：就是简化逻辑（循环）代码。
 *		3. 核心规律：
 *				1. 通过数值带入的方式，查找逻辑规律：
 *						就是有相似运算逻辑的代码
 *				2. 通过条件判断（条件/循环）的方式，在满足条件的时候根据规律调用自己的方法。如果不满足就不会自己的方法，这就是出口
 *	
 *		4. 注意事项：
 *			1. 递归必须 有出口
 *			2. 能用循环用循环，不要用递归，因为效率极其低下。
 *			为什么效率低下？
 *				方法的调用都是创建新栈帧，入栈，而栈层级是有限制的
 *			StackOverflowError : 栈内存溢出错误。
 *
 *		5. 使用场景：
 *			1. 树状结构数据或者菜单结构的数据查询
 *			2. 有相似逻辑运算的结构
 *			3. 适用于层级结构少，数据量小的场景。（最重要）如果层级多，且数据量大用循环。
 *
 *		6. 解决了哪些问题：
 *			1. 汉诺塔
 *			2. 斐波拉契数列
 *			...
 */
public class FileTools {

	public static void main(String[] args) {
		File file = new File("E:/1107-java资料/1107_java上课资料");
		printFile(file);
	}
	
	/**
	 * 设计一个方法，传入一个文件File对象，将该File对象下所有的文件后缀是.java的文件打印出来
	 * 
	 * 思路：
	 * 		1. 先获取file所有子文件（夹）
	 * 		2. 先判断当前遍历到的第一个子文件（夹），非空判断，避免空指针异常
	 * 		3. 如果当前遍历到的File对象是一个文件，直接判断后缀是不是.java，如果是打印
	 * 		4. 如果当前遍历到的File对象是一个文件夹，继续获取当前遍历到的文件夹的下一级
	 * 			条件满足，调用自己的方法
	 * 		
	 */
	public static void printFile(File file) {
		//非空判断，避免空指针异常
		if (file == null || !file.exists()) {//!file.exists()表示如果硬盘上不存在这个文件对象，就直接结束方法
			return;
		}
		//先获取file所有子文件（夹）
		File[] listFiles = file.listFiles();
		//排除文件没有下一级的情况
		if (listFiles != null) {
			//遍历当前每一个子文件（夹）
			for (File f : listFiles) {
				//3. 如果当前遍历到的File对象是一个文件，直接判断后缀是不是.java，如果是打印
				if (f.isFile() && f.getName().endsWith(".avi")) {
					//满足条件直接打印
					System.out.println(f.getName());
				}else if (f.isDirectory()) {
					//4. 如果当前遍历到的File对象是一个文件夹，继续获取当前遍历到的文件夹的下一级,条件满足，调用自己的方法
					printFile(f);
				}
			}
		}else {//表示file是一个文件，直接判断后缀是不是.java
			if (file.getName().endsWith(".avi")) {
				//满足条件直接打印
				System.out.println(file.getName());
			}
		}
		
	}
	
}
